home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / src / pl-funct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-07  |  6.4 KB  |  271 lines

  1. /*  $Id: pl-funct.c,v 1.18 1997/08/07 07:57:57 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     See ../LICENCE to find out about your rights.
  5.     jan@swi.psy.uva.nl
  6.  
  7.     Purpose: Functor (re) allocation
  8. */
  9.  
  10. /*#define O_DEBUG 1*/
  11. #include "pl-incl.h"
  12.  
  13. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  14. Functor (name/arity) handling.  A functor is a unique object (like atoms).
  15. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  16.  
  17. #define functor_buckets (GD->functors.buckets)
  18. #define functor_locked  (GD->functors.locked)
  19. #define functorDefTable (GD->functors.table)
  20.  
  21. static void      allocFunctorTable();
  22. static void      rehashFunctors();
  23.  
  24. #define lockFunctors() { functor_locked++; }
  25. #define unlockFunctors() if ( --functor_locked == 0 && \
  26.                   functor_buckets * 2 < GD->statistics.functors ) \
  27.                rehashFunctors()
  28.  
  29.  
  30. static void
  31. registerFunctor(FunctorDef fd)
  32. { int n = entriesBuffer(&functor_array, FunctorDef);
  33.   int amask = (fd->arity < F_ARITY_MASK ? fd->arity : F_ARITY_MASK);
  34.     
  35.   fd->functor = MK_FUNCTOR(n, amask);
  36.   addBuffer(&functor_array, fd, FunctorDef);
  37.  
  38.   DEBUG(0, assert(fd->arity == arityFunctor(fd->functor)));
  39. }
  40.  
  41.  
  42. functor_t
  43. lookupFunctorDef(atom_t atom, int arity)
  44. { int v = pointerHashValue(atom, functor_buckets);
  45.   FunctorDef f;
  46.  
  47.   DEBUG(9, Sdprintf("Lookup functor %s/%d = ", stringAtom(atom), arity));
  48.   for(f = functorDefTable[v]; f && !isTableRef(f); f = f->next)
  49.   { if (atom == f->name && f->arity == arity)
  50.     { DEBUG(9, Sdprintf("%ld (old)\n", f));
  51.       return f->functor;
  52.     }
  53.   }
  54.   f = (FunctorDef) allocHeap(sizeof(struct functorDef));
  55.   f->next    = functorDefTable[v];
  56.   f->functor = 0L;
  57.   f->name    = atom;
  58.   f->arity   = arity;
  59.   f->flags   = 0;
  60.   functorDefTable[v] = f;
  61.   GD->statistics.functors++;
  62.  
  63.   DEBUG(9, Sdprintf("%ld (new)\n", f));
  64.  
  65.   if ( functor_buckets * 2 < GD->statistics.functors && !functor_locked )
  66.     rehashFunctors();
  67.  
  68.   registerFunctor(f);
  69.   return f->functor;
  70. }
  71.  
  72.  
  73. static void
  74. rehashFunctors()
  75. { FunctorDef *oldtab = functorDefTable;
  76.   int oldbucks       = functor_buckets;
  77.   FunctorDef f, n;
  78.   int done = 0;
  79.  
  80.   startCritical;
  81.   functor_buckets *= 2;
  82.   allocFunctorTable();
  83.  
  84.   DEBUG(1, Sdprintf("Rehashing functor-table to %d entries\n",
  85.             functor_buckets));
  86.  
  87.   for(f = oldtab[0]; f; f = n)
  88.   { int v;
  89.  
  90.     while(isTableRef(f) )
  91.     { f = unTableRef(FunctorDef, f);
  92.       if ( !f )
  93.     goto out;
  94.     }
  95.     n = f->next;
  96.     done++;
  97.     v = pointerHashValue(f->name, functor_buckets);
  98.     f->next = functorDefTable[v];
  99.     functorDefTable[v] = f;
  100.   }
  101.  
  102. out:
  103.   assert(done == GD->statistics.functors);
  104.   freeHeap(oldtab, oldbucks * sizeof(FunctorDef));
  105.   endCritical;
  106. }
  107.  
  108.  
  109.  
  110. functor_t
  111. isCurrentFunctor(atom_t atom, int arity)
  112. { int v = pointerHashValue(atom, functor_buckets);
  113.   FunctorDef f;
  114.  
  115.   for(f = functorDefTable[v]; f && !isTableRef(f); f = f->next)
  116.   { if (atom == f->name && f->arity == arity)
  117.       return f->functor;
  118.   }
  119.  
  120.   return 0;
  121. }
  122.  
  123. typedef struct
  124. { atom_t name;
  125.   char   arity;
  126. } builtin_functor;
  127.  
  128. #define FUNCTOR(n, a) { n, a }
  129. static const builtin_functor functors[] = {
  130. #include "pl-funct.ic"
  131. FUNCTOR(NULL_ATOM, 0)
  132. };
  133. #undef FUNCTOR
  134.  
  135.  
  136. static void
  137. allocFunctorTable()
  138. { FunctorDef *f;
  139.   int n;
  140.  
  141.   functorDefTable = allocHeap(functor_buckets * sizeof(FunctorDef));
  142.  
  143.   for(n=0, f=functorDefTable; n < (functor_buckets-1); n++, f++)
  144.     *f = makeTableRef(f+1);
  145.   *f = NULL;
  146. }
  147.  
  148.  
  149. static void
  150. registerBuiltinFunctors()
  151. { int size = sizeof(functors)/sizeof(builtin_functor) - 1;
  152.   FunctorDef f = allocHeap(size * sizeof(struct functorDef));
  153.   const builtin_functor *d;
  154.  
  155.   GD->statistics.functors = size;
  156.  
  157.   for(d = functors; d->name; d++, f++)
  158.   { int v = pointerHashValue(d->name, functor_buckets);
  159.  
  160.     f->name             = d->name;
  161.     f->arity            = d->arity;
  162.     f->next             = functorDefTable[v];
  163.     functorDefTable[v]  = f;
  164.     registerFunctor(f);
  165.   }
  166. }
  167.  
  168.  
  169. void
  170. initFunctors(void)
  171. { functor_buckets = FUNCTORHASHSIZE;
  172.   initBuffer(&functor_array);
  173.   allocFunctorTable();
  174.   registerBuiltinFunctors();
  175. }
  176.  
  177.  
  178. #if TEST
  179. checkFunctors()
  180. { register FunctorDef f;
  181.   int n;
  182.  
  183.   for( n=0; n < functor_buckets; n++ )
  184.   { f = functorDefTable[n];
  185.     for( ;f && !isTableRef(f); f = f->next )
  186.     { if ( f->arity < 0 || f->arity > 10 )    /* debugging only ! */
  187.         Sdprintf("[ERROR: Functor %ld has dubious arity: %d]\n", f, f->arity);
  188.       if ( !isArom(f->name) )
  189.         Sdprintf("[ERROR: Functor %ld has illegal name: %ld]\n", f, f->name);
  190.       if ( !( f->next == (FunctorDef) NULL ||
  191.           isTableRef(f->next) ||
  192.           inCore(f->next)) )
  193.     Sdprintf("[ERROR: Functor %ld has illegal next: %ld]\n", f, f->next);
  194.     }
  195.     if ( (isTableRef(f) &&
  196.      (unTableRef(FunctorDef, f) != &functorDefTable[n+1])) )
  197.       Sdprintf("[ERROR: Bad continuation pointer (fDef, n=%d)]\n", n);
  198.     if ( f == (FunctorDef) NULL && n != (functor_buckets-1) )
  199.       Sdprintf("[ERROR: illegal end pointer (fDef, n=%d)]\n", n);
  200.   }
  201. }
  202. #endif
  203.  
  204. word
  205. pl_current_functor(term_t name, term_t arity, word h)
  206. { FunctorDef fdef;
  207.   atom_t nm;
  208.   int  ar;
  209.   int name_is_atom;
  210.   mark m;
  211.  
  212.   switch( ForeignControl(h) )
  213.   { case FRG_FIRST_CALL:
  214.       if ( (name_is_atom = PL_get_atom(name, &nm)) &&
  215.        PL_get_integer(arity, &ar) )
  216.     return isCurrentFunctor(nm, ar) ? TRUE : FALSE;
  217.  
  218.       if ( !(PL_is_integer(arity) || PL_is_variable(arity)) )
  219.     return warning("current_functor/2: instantiation fault");
  220.  
  221.       if ( name_is_atom )
  222.       { int v = pointerHashValue(nm, functor_buckets);
  223.     
  224.     fdef = functorDefTable[v];
  225.       } else
  226.       { if ( !PL_is_variable(name) )
  227.       return warning("current_functor/2: instantiation fault");
  228.  
  229.     fdef = functorDefTable[0];
  230.       }
  231.       lockFunctors();
  232.       break;
  233.     case FRG_REDO:
  234.       fdef = ForeignContextPtr(h);
  235.       name_is_atom = PL_is_atom(name);
  236.       break;
  237.     case FRG_CUTTED:
  238.     default:
  239.       unlockFunctors();
  240.       succeed;
  241.   }
  242.  
  243.   Mark(m);
  244.   DEBUG(9, Sdprintf("current_functor(): fdef = %ld\n", fdef));
  245.   for(; fdef; fdef = fdef->next)
  246.   { if ( isTableRef(fdef) )
  247.     { if ( name_is_atom )
  248.     goto out;
  249.  
  250.       do
  251.       { fdef = unTableRef(FunctorDef, fdef);
  252.     if ( !fdef )
  253.       goto out;
  254.       } while( isTableRef(fdef) );
  255.     }
  256.     if ( fdef->arity == 0 )
  257.       continue;
  258.     Undo(m);
  259.     if ( !PL_unify_atom(name, fdef->name) ||
  260.      !PL_unify_integer(arity, fdef->arity) )
  261.       continue;
  262.     DEBUG(9, Sdprintf("Returning backtrack point %ld\n", fdef->next));
  263.  
  264.     return_next_table(FunctorDef, fdef, unlockFunctors());
  265.   }
  266.  
  267. out:
  268.   unlockFunctors();
  269.   fail;
  270. }
  271.